package com.uplift.mgt.building.service.impl;

import com.github.pagehelper.PageHelper;
import com.uplift.common.base.BusinessException;
import com.uplift.common.base.ServiceReslut;
import com.uplift.common.utils.JExcelReadUtils;
import com.uplift.common.utils.UUIDGenerater;
import com.uplift.mgt.building.dao.*;
import com.uplift.mgt.building.model.*;
import com.uplift.mgt.building.service.IBuildingService;
import com.uplift.mgt.building.service.IRealtyInfoService;
import com.uplift.mgt.building.service.IRealtyLeaseService;
import com.uplift.mgt.customer.service.ICustomerService;
import com.uplift.mgt.sys.service.IDictService;
import com.uplift.sec.SecurityContext;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import java.math.BigDecimal;
import java.util.*;

@Service
@Transactional
public class RealtyLeaseServiceImpl implements IRealtyLeaseService {

	@Autowired
	private RealtyLeaseMapper realtyLeaseMapper;
	@Autowired
	private RealtyRoomMapper realtyRoomMapper;
	@Autowired
	private RealtyInfoMapper realtyInfoMapper;
	@Autowired
	private IRealtyInfoService realtyInfoService;

	@Autowired
	private ICustomerService customerService;

	/** excle 每列的字段名称 */
	private String[] excel_cloum_names = new String[] {"客户名称","楼盘类型","楼盘名称","房间号","住户姓名","住户性别","住户年龄",
			"是否有宠物","租金","管理/公益费","礼金","押金","保证金","保证会社","保证人","起租日","约满日","免租期","状态"};

	@Override
	public List<Map<String, Object>> queryRealtyLease(RealtyLease realtyLease) {
		PageHelper.startPage(realtyLease.getPage(), realtyLease.getLimit());
		return this.realtyLeaseMapper.selectRealtyLease(realtyLease);
	}

	@Override
	public List<Map<String, Object>> queryAllRealtyLease(RealtyLease realtyLease) {
		return this.realtyLeaseMapper.selectRealtyLease(realtyLease);
	}

	@Override
	public ServiceReslut addRealtyLease(RealtyLease realtyLease) {

		Map<String, Object> sessionUser = SecurityContext.getSessionUser();
		if(sessionUser == null) {
			return ServiceReslut.newServiceReslut(0, "获取登录用户信息失败");
		}

		realtyLease.setCreateUserId((String) sessionUser.get("id"));

		//验证房间状态
		if(StringUtils.isBlank(realtyLease.getRoomId())) {
			return ServiceReslut.newServiceReslut(0, "房间id为空");
		}

		RealtyRoomModel realtyRoomModel = new RealtyRoomModel();
		realtyRoomModel.setId(realtyLease.getRoomId());
		List<Map<String, Object>> maps = realtyRoomMapper.selectRealtyRoom(realtyRoomModel);
		if(maps==null || maps.size()<0) {
			return ServiceReslut.newServiceReslut(0, "获取房间失败");
		}

		if(!StringUtils.equals(maps.get(0).get("state").toString(), "1")) {
			return ServiceReslut.newServiceReslut(0, "房间不为空房状态，不能添加租约，请先结束之前租约。");
		}

		realtyLease.setId(UUID.randomUUID().toString().replaceAll("-", ""));
		realtyLease.setState("1");
		realtyLease.setCreateTime(new Date());

		realtyRoomModel.setState("2");		//将房间状态设置为租赁中状态
		realtyRoomModel.setUpdateTime(new Date());
		realtyRoomMapper.updateRealtyRoom(realtyRoomModel);

		//广告处理
		handleAds(realtyLease);

		countReturnRate(realtyLease);		//计算表面回报率

		return ServiceReslut.newServiceReslut(realtyLeaseMapper.insertRealtyLease(realtyLease), "");
	}

	/**
	 * 计算回报率
	 * @param realtyLease
	 */
	private void countReturnRate(RealtyLease realtyLease) {
		if(realtyLease.getRent() == null) {
			return;
		}

		RealtyInfo realtyInfo = new RealtyInfo();
		realtyInfo.setId(realtyLease.getRealtyId());

		List<Map<String, Object>> realtyInfos = realtyInfoMapper.selectRealtyInfo(realtyInfo);
		if(realtyInfos==null || realtyInfos.size()<=0) {
			return;
		}

		Map<String, Object> realytMap = realtyInfos.get(0);
		BigDecimal buyPrice = new BigDecimal(realytMap.get("buyPrice")==null?"0":realytMap.get("buyPrice").toString());
		if(buyPrice.longValue() == 0) {
			return;
		}
		BigDecimal returnRate = realtyLease.getRent().add(realtyLease.getManageCost()).multiply(new BigDecimal(12));

		if(StringUtils.equals(realytMap.get("typeCode").toString(), "BUILD")) {		//如果是一栋则需要计算一栋正在出租中的租金及管理费
			returnRate = returnRate.add(countBuildRent(realytMap));
		}

		returnRate = returnRate.multiply(new BigDecimal(100));
		returnRate = returnRate.divide(buyPrice.multiply(new BigDecimal(10000)),1,BigDecimal.ROUND_HALF_UP);
		realtyInfo.setReturnRate(returnRate.toString());
		realtyInfoMapper.updateRealtyInfo(realtyInfo);

		realtyLease.setReturnRate(returnRate.toString());
	}

	/**
	 * 计算一栋所有租金及管理费
	 * @param realytMap
	 * @return
	 */
	private BigDecimal countBuildRent(Map<String, Object> realytMap) {

		RealtyLease realtyLease = new RealtyLease();
		realtyLease.setRealtyId(realytMap.get("id").toString());
		realtyLease.setState("1");			//租赁中
		List<Map<String, Object>> maps = realtyLeaseMapper.selectRealtyLease(realtyLease);

		BigDecimal returnRate = new BigDecimal(0);
		BigDecimal _returnRate;
		if(maps!=null && maps.size()>0) {
			for (Map<String, Object> map : maps) {
				_returnRate = new BigDecimal(0);
				returnRate = returnRate.add(_returnRate.add((BigDecimal) map.get("rent")).add((BigDecimal) map.get("manageCost")).multiply(new BigDecimal(12)));
			}

		}

		return returnRate;
	}

	@Override
	public ServiceReslut updateRealtyLease(RealtyLease realtyLease) {
		//广告处理
		handleAds(realtyLease);

		realtyLease.setRoomId(null);
		realtyLease.setRoomNum(null);
		realtyLease.setCustomerName(null);
		realtyLease.setRealtyId(null);

		realtyLease.setUpdateTime(new Date());

		countReturnRate(realtyLease);		//计算表面回报率
		return ServiceReslut.newServiceReslut(realtyLeaseMapper.updateRealtyLease(realtyLease),"");
	}

	@Override
	public ServiceReslut deleteRealtyLease(RealtyLease realtyLease) {
		realtyLease.setState("0");		//删除状态
		realtyLease.setUpdateTime(new Date());
		return ServiceReslut.newServiceReslut(realtyLeaseMapper.updateRealtyLease(realtyLease),"");
	}

	@Override
	public ServiceReslut endRealtyLease(RealtyLease realtyLease) {
		List<Map<String, Object>> maps = realtyLeaseMapper.selectRealtyLease(realtyLease);
		if(maps==null || maps.size()<=0) {
			return ServiceReslut.newServiceReslut(0,"查询租约信息失败！");
		}

		//更新关联房间状态为空房状态
		RealtyRoomModel realtyRoomModel = new RealtyRoomModel();
		realtyRoomModel.setId(maps.get(0).get("roomId").toString());
		realtyRoomModel.setState("1");		//将房间设置为空房状态
		realtyRoomModel.setUpdateTime(new Date());
		realtyRoomMapper.updateRealtyRoom(realtyRoomModel);

//		realtyLease.setAge(-1);
		realtyLease.setState("2");		//将租约状态设置为已结束状态
		realtyLease.setUpdateTime(new Date());
		return ServiceReslut.newServiceReslut(realtyLeaseMapper.updateRealtyLease(realtyLease),"");
	}

	@Override
	public List<Map<String, Object>> queryRealtyLeaseAd(String realtyLeaseId) {

		if(StringUtils.isBlank(realtyLeaseId)) {
			return null;
		}
		RealtyLease realtyLease = new RealtyLease();
		realtyLease.setId(realtyLeaseId);

		return realtyLeaseMapper.selectRealtyLeaseAd(realtyLease);
	}

	/**
	 * 处理广告信息
	 * @param realtyLease
	 */
	private void handleAds(RealtyLease realtyLease) {
		RealtyALModel realtyALModel = new RealtyALModel();
		realtyALModel.setLeaseId(realtyLease.getId());
		realtyLeaseMapper.deleteLeaseAd(realtyALModel);			//删除租约关联广告

		if(StringUtils.isBlank(realtyLease.getAds())) {
			return;
		}

		String[] ad = StringUtils.split(realtyLease.getAds(), ",");
		for (String s : ad) {
			realtyALModel.setId(UUIDGenerater.generate());
			realtyALModel.setAdId(s);
			realtyLeaseMapper.addLeaseAd(realtyALModel);
		}
	}

	@Override
	public void importLease(MultipartHttpServletRequest request) {
		try {
			MultipartFile file = request.getFile("file");
			if(file == null) {
				throw new BusinessException("导入失败，导入文件为空", 400, null);
			}
			List<Map<String, String>> datas = JExcelReadUtils.readExcelSheet1(file.getInputStream(), -1, 2, -1);
			if(CollectionUtils.isEmpty(datas)) {
				throw new BusinessException("导入失败，内容为空", 400, null);
			}

			if(!JExcelReadUtils.checkImprtExcelFormat(datas.get(0), excel_cloum_names)) {
				throw new BusinessException("导入失败，excle 模版错误", 400, null);
			}

			List<RealtyLease> realtyLeases = createLease(datas);
			if(CollectionUtils.isEmpty(realtyLeases)) {
				throw new BusinessException("导入失败，内容为空", 400, null);
			}

			for (RealtyLease realtyLease: realtyLeases) {
				saveImportLease(realtyLease);
			}
		} catch (Exception e) {
			if (e instanceof BusinessException) {
				throw new BusinessException(e);
			} else {
				throw new BusinessException("导入失败", 400, null);
			}
		}
	}

	private void saveImportLease(RealtyLease realtyLease) {
		if(StringUtils.equals(realtyLease.getState(), "1")) {
			RealtyRoomModel realtyRoomModel = new RealtyRoomModel();
			realtyRoomModel.setId(realtyLease.getRoomId());
			realtyRoomModel.setState("2");		//将房间状态设置为租赁中状态
			realtyRoomModel.setUpdateTime(new Date());
			realtyRoomMapper.updateRealtyRoom(realtyRoomModel);

			countReturnRate(realtyLease);		//计算表面回报率
		}

		realtyLeaseMapper.insertRealtyLease(realtyLease);
	}

	private List<RealtyLease> createLease(List<Map<String, String>> datas) {
		List<RealtyLease> realtyLeases = new ArrayList<>();

		for (int i = 1; i < datas.size(); i++) {
			realtyLeases.add(createRealtyLease(datas.get(i), i));
		}

		return realtyLeases;
	}

	private RealtyLease createRealtyLease(Map<String, String> data, int row) {
		if(StringUtils.isBlank(data.get("0"))) {
			throw new BusinessException(String.format("第[%s]条导入失败，客户名称不能为空", row, data.get("0")), 400, null);
		}

		Map<String, Object> customerMap = customerService.queryCustomerByName(data.get("0"));
		if(customerMap == null) {
			throw new BusinessException(String.format("第[%s]条导入失败，客户名称[%s]不存在", row,data.get("0")), 400, null);
		}

		String typeName = data.get("1");
		if(StringUtils.isBlank(typeName)) {
			throw new BusinessException(String.format("第[%s]条导入失败，客户名称[%s] ，公寓类型不能为空", row,data.get("0")), 400, null);
		}
		String buildName = data.get("2");
		if(StringUtils.isBlank(buildName)) {
			throw new BusinessException(String.format("第[%s]条导入失败，客户名称[%s] ，楼盘名称不能为空", row,data.get("0")), 400, null);
		}
		String roomNum = data.get("3");
		if(StringUtils.isBlank(roomNum)) {
			throw new BusinessException(String.format("第[%s]条导入失败，客户名称[%s] ，楼盘名称[%s]房间号不能为空", row,data.get("0"), data.get("2")), 400, null);
		}

		RealtyInfo realtyInfo = new RealtyInfo();
		realtyInfo.setCustomerName(data.get("0"));
		realtyInfo.setBuildingName(buildName);
		realtyInfo.setRoomNum(roomNum);
		Map<String, Object> roomMap = realtyInfoService.queryRealtyRoom(realtyInfo);
		if(roomMap == null) {
			throw new BusinessException(String.format("第[%s]条导入失败，客户名称[%s] ，楼盘名称[%s]，房间号[%s] 查询失败", row,data.get("0"),  buildName, roomNum), 400, null);
		}
		String leaseState = StringUtils.equals(data.get("18"), "进行中")?"1":"2";
		if(StringUtils.equals(leaseState, "1") && StringUtils.equals(roomMap.get("state").toString(), "2")) {
			throw new BusinessException(String.format("第[%s]条导入失败，客户名称[%s] ，楼盘名称[%s]，房间号[%s] 正在租赁中，不能再添加租约",row,data.get("0"), buildName, roomNum), 400, null);
		}

		RealtyLease realtyLease = new RealtyLease();
		realtyLease.setCustomerName(customerMap.get("name").toString());
		realtyLease.setRealtyId(roomMap.get("realtyId").toString());
		realtyLease.setInName(data.get("4"));
		realtyLease.setSex(StringUtils.equals(data.get("5"), "男")?"1":"0");
		realtyLease.setAge(data.get("6"));
		realtyLease.setIsHasPet(StringUtils.equals(data.get("7"), "是")?"1":"0");
		realtyLease.setRent(new BigDecimal(data.get("8")));
		realtyLease.setManageCost(new BigDecimal(data.get("9")));
		realtyLease.setCashGift(new BigDecimal(data.get("10")));
		realtyLease.setCashCost(new BigDecimal(data.get("11")));
		realtyLease.setDeposit(new BigDecimal(data.get("12")));
		realtyLease.setEnsure(data.get("13"));
		realtyLease.setVoucher(data.get("14"));
		realtyLease.setStartDate(data.get("15"));
		realtyLease.setEndDate(data.get("16"));
		realtyLease.setRentFree(data.get("17"));
		realtyLease.setState(leaseState);
		realtyLease.setRoomId(roomMap.get("id").toString());

		Map<String, Object> sessionUser = SecurityContext.getSessionUser();
		realtyLease.setCreateUserId((String) sessionUser.get("id"));
		realtyLease.setId(UUID.randomUUID().toString().replaceAll("-", ""));
		realtyInfo.setCreateTime(new Date());

		return realtyLease;
	}
}
